package top.continew.admin.controller.specification;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.continew.admin.business.model.query.KnowledgePointTreeMultiSpecTypeQuery;
import top.continew.admin.business.model.query.SpecificationTypeQuery;
import top.continew.admin.business.model.req.SpecificationTypeReq;
import top.continew.admin.business.model.resp.KnowledgePointTreeResp;
import top.continew.admin.business.model.resp.SpecificationTypeDetailResp;
import top.continew.admin.business.model.resp.SpecificationTypeResp;
import top.continew.admin.business.service.SpecificationTypeService;
import top.continew.admin.common.controller.BaseController;
import top.continew.starter.core.util.ReflectUtils;
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
import top.continew.starter.extension.crud.annotation.TreeField;
import top.continew.starter.extension.crud.autoconfigure.CrudProperties;
import top.continew.starter.extension.crud.autoconfigure.CrudTreeProperties;
import top.continew.starter.extension.crud.enums.Api;
import top.continew.starter.web.model.R;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 规格类型管理 API
 *
 * @author sheng_chao
 * @since 2025/03/04 20:47
 */
@Tag(name = "规格类型数改写 API")
@RestController
@RequestMapping("")
public class SpecificationTypeTreeController  {
    @Autowired
    private SpecificationTypeService specificationTypeService;
    @GetMapping("/business/specificationType/tree")
    public R<List<Tree<Long>>> getSpecificationTypeTree(SpecificationTypeQuery query) {
        if (query==null){
            query=new SpecificationTypeQuery();
        }
        List<SpecificationTypeResp> specificationTypeRespList=specificationTypeService.listByQuery(query);
        if (CollUtil.isEmpty(specificationTypeRespList)) {
            return R.ok(List.of());
        } else {
            CrudProperties crudProperties = (CrudProperties) SpringUtil.getBean(CrudProperties.class);
            CrudTreeProperties treeProperties = crudProperties.getTree();
            TreeField treeField = KnowledgePointTreeResp.class.getDeclaredAnnotation(TreeField.class);
            TreeNodeConfig treeNodeConfig= treeProperties.genTreeNodeConfig(treeField);
            Long rootId = treeField.rootId();
            List<Field> fieldList = ReflectUtils.getNonStaticFields(SpecificationTypeResp.class);

            return R.ok( TreeUtil.build(specificationTypeRespList, rootId, treeNodeConfig, (node, tree) -> {
                tree.setId((Long) ReflectUtil.invoke(node, CharSequenceUtil.genGetter("id"), new Object[0]));
                tree.setParentId((Long)ReflectUtil.invoke(node, CharSequenceUtil.genGetter("parentId"), new Object[0]));
                tree.setName((CharSequence)ReflectUtil.invoke(node, CharSequenceUtil.genGetter("name"), new Object[0]));
                tree.setWeight((Comparable)ReflectUtil.invoke(node, CharSequenceUtil.genGetter("sort"), new Object[0]));
                fieldList.removeIf((f) -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), new CharSequence[]{treeField.value(), treeField.parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()}));
                fieldList.forEach((f) -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f.getName()), new Object[0])));
            }));
        }
    }
}